package com.ball.tools;

/*
 * #%L
 * NanoHttpd-Samples
 * %%
 * Copyright (C) 2012 - 2015 nanohttpd
 * %%
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice, this
 *	list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *	this list of conditions and the following disclaimer in the documentation
 *	and/or other materials provided with the distribution.
 * 
 * 3. Neither the name of the nanohttpd nor the names of its contributors
 *	may be used to endorse or promote products derived from this software without
 *	specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * #L%
 */

/**
 * Created by vnnv on 7/17/15.
 * Simple httpd server based on NanoHTTPD
 * Read the source. Everything is there.
 */

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

import org.nanohttpd.protocols.http.IHTTPSession;
import org.nanohttpd.protocols.http.response.IStatus;
import org.nanohttpd.protocols.http.response.Response;
import org.nanohttpd.protocols.http.response.Status;
import org.nanohttpd.router.RouterNanoHTTPD;
import org.nanohttpd.util.ServerRunner;

public class AppNanolets extends RouterNanoHTTPD {

	private static final int PORT = 9090;

	public static class UserHandler extends DefaultHandler {

		@Override
		public String getText() {
			return "not implemented";
		}

		public String getText(Map<String, String> urlParams, IHTTPSession session) {
			StringBuilder text = new StringBuilder(1024);
			text.append("<html><body>User handler. Method: ").append(session.getMethod().toString()).append("<br/>");
			text.append("\r\n<h1>Uri parameters:</h1>");
			for (Map.Entry<String, String> entry : urlParams.entrySet()) {
				String key = entry.getKey();
				String value = entry.getValue();
				text.append("\r\n<div> Param: ").append(key).append("&nbsp;Value: ").append( value).append("</div>");
			}
			text.append("\r\n<h1>Query parameters:</h1>");
			for (Map.Entry<String, List<String>> entry : session.getParameters().entrySet()) {
				String key = entry.getKey();
				List<String> value = entry.getValue();
				String html;
				if(value==null || value.isEmpty()){
					html="";
				}else if(value.size()==0){
					html=value.get(0);
				}else{
					html=value.toString();
				}
				html=html.replace("<", "&lt;");
				text.append("<p>Param '");
				text.append(key);
				text.append("' = ");
				text.append(html);
				text.append("</p>");
			}
			text.append("\r\n</body></html>");

			return text.toString();
		}

		@Override
		public String getMimeType() {
			return "text/html";
		}

		@Override
		public IStatus getStatus() {
			return Status.OK;
		}

		public Response get(UriResource uriResource, Map<String, String> urlParams, IHTTPSession session) {
			String text = getText(urlParams, session);
			ByteArrayInputStream inp = new ByteArrayInputStream(text.getBytes());
			int size = text.getBytes().length;
			return Response.newFixedLengthResponse(getStatus(), getMimeType(), inp, size);
		}

	}

	static public class StreamUrl extends DefaultStreamHandler {

		@Override
		public String getMimeType() {
			return "text/plain";
		}

		@Override
		public IStatus getStatus() {
			return Status.OK;
		}

		@Override
		public InputStream getData() {
			return new ByteArrayInputStream("a stream of data ;-)".getBytes());
		}

	}

	public static class StaticPageTestHandler extends StaticPageHandler {

		@Override
		protected BufferedInputStream fileToInputStream(File fileOrdirectory) throws IOException {
			if ("exception.html".equals(fileOrdirectory.getName())) {
				throw new IOException("trigger something wrong");
			}
			return super.fileToInputStream(fileOrdirectory);
		}
	}

	/**
	 * Create the server instance
	 */
	public AppNanolets() throws IOException {
		super(PORT);
		addMappings();
		System.out.println("\nRunning! Point your browers to http://localhost:" + PORT + "/ \n");
	}

	/**
	 * Add the routes Every route is an absolute path Parameters starts with ":"
	 * Handler class should implement @UriResponder interface If the handler not
	 * implement UriResponder interface - toString() is used
	 */
	@Override
	public void addMappings() {
		super.addMappings();
		addRoute("/user", UserHandler.class);
		addRoute("/user", UserHandler.class); // add it twice to execute the
											  // priority == priority case
		addRoute("/user/help", GeneralHandler.class);
		addRoute("/user/:id", UserHandler.class);
		addRoute("/general/:param1/:param2", GeneralHandler.class);
		addRoute("/photos/:customer_id/:photo_id", null);
		addRoute("/test", String.class);
		addRoute("/interface", UriResponder.class); // this will cause an error
													// when called
		addRoute("/toBeDeleted", String.class);
		removeRoute("/toBeDeleted");
		addRoute("/stream", StreamUrl.class);
		addRoute("/browse/(.)+", StaticPageTestHandler.class, new File("home").getAbsoluteFile());
	}

	/**
	 * Main entry point
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		ServerRunner.run(AppNanolets.class);
	}
}
